package com.saas.ability.core.base.test;

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

import java.net.URL;

import org.hamcrest.Matchers;
import org.junit.Before;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;

import com.alibaba.fastjson.JSONObject;
import com.saas.ability.core.base.constant.retcode.RetCode;
import com.saas.ability.core.base.protocol.BaseOutput;
import com.saas.ability.core.base.util.FileUtil;
import com.saas.ability.core.base.util.ResourceUtil;
import com.saas.ability.core.base.util.RetCodeUtil;
import com.google.common.io.Resources;

import lombok.extern.slf4j.Slf4j;

/**
 * @description: Mock测试基类
 */
@Slf4j
public class BaseMockMvn {

    @Autowired
    protected WebApplicationContext context;

    protected MockMvc mockMvc;

    @Before
    public void setup() throws Exception { //这个方法在每个方法执行之前都会执行一遍
        //初始化MockMvc对象
        this.mockMvc = MockMvcBuilders.webAppContextSetup(context).build();
    }
    
    
    protected void mockPost(String mockDataPath, String url) throws Exception {
        log.info("===============================start单元测试================================");
        String data = ResourceUtil.readData(mockDataPath);
        this.mockMvc
			.perform(post(url)
	        .contentType(MediaType.APPLICATION_JSON)// 数据的格式
	        .content(data)) // 请求的url,请求的方法是post
			.andExpect(status().isOk()) // 返回的状态是200
			.andDo(print()) // 打印出请求和相应的内容
			.andExpect(content().string(Matchers.containsString(RetCode.SUCCESS.retCode)));
        log.info("===============================end单元测试================================");
    }
    
    protected void mockGet(String url) throws Exception {
        log.info("===============================start单元测试================================");
        this.mockMvc
			.perform(get(url)) // 请求的url,请求的方法是get
			.andExpect(status().isOk()) // 返回的状态是200
			.andDo(print()) // 打印出请求和相应的内容
			.andExpect(content().string(Matchers.containsString(RetCode.SUCCESS.retCode)));
        log.info("===============================end单元测试================================");
    }

    /**
     * 单个服务公共测试
     *
     * @param jsonPath
     * @param url
     * @param methodName
     * @throws Exception
     */
    protected void baseTest(String jsonPath, String url, String methodName) throws Exception {
        log.info("===============================start单元测试================================");
        URL resource = Resources.getResource(jsonPath);
        String reqJsonStr = FileUtil.buff(resource.getFile());
        String result = mockMvc.perform(post(url)
        		.contentType(MediaType.APPLICATION_JSON)
        		.content(reqJsonStr))
                .andExpect(status().isOk())
                .andDo(print())
                .andReturn().getResponse().getContentAsString();
        BaseOutput<?> output = JSONObject.parseObject(result, BaseOutput.class);

        log.info("=========================================================================");
        if (output != null && RetCodeUtil.isSucc(output.getRetCode())) {
            log.info("URL = {}，methodName = {} 测试结果：[SUCCESS], BaseOutput = {}", url, methodName, output);
        } else {
            log.info("URL = {}，methodName = {} 测试结果：[FAIL], BaseOutput = {}", url, methodName, output);
        }
        log.info("=========================================================================");
        log.info("===============================end单元测试================================");
    }


    /**
     * 单个服务公共测试(无输入参数)
     * @param url
     * @param methodName
     * @throws Exception
     */
    protected void baseTest(String url, String methodName) throws Exception {
        log.info("===============================start单元测试================================");
        String result = mockMvc.perform(post(url).param("test","test"))
                .andExpect(status().isOk())
                .andDo(print())
                .andReturn().getResponse().getContentAsString();
        BaseOutput<?> output = JSONObject.parseObject(result, BaseOutput.class);

        log.info("=========================================================================");
        if (output != null && RetCodeUtil.isSucc(output.getRetCode())) {
            log.info("URL = {}，methodName = {} 测试结果：[SUCCESS], BaseOutput = {}", url, methodName, output);
        } else {
            log.info("URL = {}，methodName = {} 测试结果：[FAIL], BaseOutput = {}", url, methodName, output);
        }
        log.info("=========================================================================");
        log.info("===============================end单元测试================================");
    }
    
    protected void waitTime(long time){
    	try {
			Thread.sleep(time);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
    }

}
